﻿#region Header
// Copyright 2007-2011, Jerónimo Milea
// 
// This file is part of NetJsWire.
// 
//     NetJsWire is free software: you can redistribute it and/or modify
//     it under the terms of the GNU General Public License as published by
//     the Free Software Foundation, either version 3 of the License, or
//     (at your option) any later version.
// 
//     NetJsWire is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU General Public License for more details.
// 
//     You should have received a copy of the GNU General Public License
//     along with NetJsWire.  If not, see <http://www.gnu.org/licenses/>.
#endregion

using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using NetJsWire.Lite.Converters;
using NetJsWire.Lite.Designers;
using NetJsWire.Lite.Helpers;
using NetJsWire.Lite.Widgets.UI.Layout;
using Newtonsoft.Json;

namespace NetJsWire.Lite.Widgets.UI
{
    [Designer( typeof( TabPanelDesigner ) )]
    public class TabPanelLW : Panel
    {
        private readonly Dictionary<BoxComponent, RectangleF> _headersBounds = new Dictionary<BoxComponent, RectangleF>();

        private int _minTabWidth = 30;

        private bool _plain;

        private int _tabMargin = 2;

        public TabPanelLW()
        {
            base.Xtype = "tabpanel";
            base.Layout = LayoutType.Card;
        }

        [DefaultValue( 30 )]
        [JsonProperty( "minTabWidth" )]
        public int MinTabWidth
        {
            get { return _minTabWidth; }
            set
            {
                _minTabWidth = value;
                InvalidateWindow();
            }
        }

        [DefaultValue( false )]
        [JsonProperty( "plain" )]
        public bool Plain
        {
            get { return _plain; }
            set
            {
                _plain = value;
                InvalidateWindow();
            }
        }

        [DefaultValue( 2 )]
        [JsonProperty( "tabMargin" )]
        public int TabMargin
        {
            get { return _tabMargin; }
            set
            {
                _tabMargin = value;
                InvalidateWindow();
            }
        }

        [DefaultValue( 0 )]
        [JsonProperty( "activeItem", DefaultValueHandling = DefaultValueHandling.Include )]
        public override int ActiveItem
        {
            get
            {
                return base.ActiveItem;
            }
            set
            {
                base.ActiveItem = value;
            }
        }

        [DefaultValue( LayoutType.Card )]
        public override LayoutType Layout
        {
            get
            {
                return LayoutType.Card;
            }
            set
            {
            }
        }

        [DefaultValue( "tabpanel" )]
        [TypeConverter( typeof( XtypeTypeConverter ) )]
        public override string Xtype
        {
            get
            {
                return "tabpanel";
            }
            set { }
        }

        internal override void DrawTitleBar( Graphics g, Rectangle bounds )
        {
            _headersBounds.Clear();
            if ( null == Items )
                return;
            var backgroundColor = Color.FromArgb( 206, 217, 231 );
            using ( var br = new SolidBrush( backgroundColor ) )
            {
                g.FillRectangle( br, new Rectangle( bounds.X + BorderWidth, bounds.Y + BorderWidth, bounds.Width - ( BorderWidth * 2 ), TitleBarHeight + BorderWidth ) );
            }
            var childrens = Items.OfType<Panel>();
            if ( childrens != null )
            {
                var foreTabColor = Color.FromArgb( 206, 223, 245 );
                var backTabsColor = Color.FromArgb( 222, 236, 253 );
                var index = 0;
                //var borderPadding = 3;
                var tabPadding = 0;

                using ( var pen = new Pen( FrameBorderColor ) )
                {
                    g.DrawLine( pen, bounds.X,
                                bounds.Y + TitleBarHeight - 3,
                                bounds.X + BorderWidth + bounds.Width - ( BorderWidth * 2 ),
                                bounds.Y + TitleBarHeight - 3 );

                    //g.DrawLine( pen, bounds.X,
                    //            bounds.Y + TITLE_BAR_HEIGHT + BorderWidth,
                    //            bounds.X + BorderWidth + bounds.Width - ( BorderWidth * 2 ),
                    //            bounds.Y + TITLE_BAR_HEIGHT + BorderWidth );
                }

                bounds.Inflate( -BorderWidth, -BorderWidth );

                using ( var br = new SolidBrush( backTabsColor ) )
                {
                    g.FillRectangle( br, new Rectangle( bounds.X + BorderWidth, bounds.Y,
                                                        bounds.Width - ( BorderWidth * 2 ),
                                                        TitleBarHeight - 1 ) );
                }

                foreach ( var children in childrens )
                {
                    var childRect = RoundedRectangle.Create( tabPadding + ( 80 * index ) + bounds.X + TabMargin,
                                                             bounds.Y + 2, 80,
                                                             TitleBarHeight - 6, 3,
                                                             RoundedRectangle.RectangleCorners.TopLeft |
                                                             RoundedRectangle.RectangleCorners.TopRight );
                    _headersBounds.Add( children, childRect.GetBounds() );
                    using ( var pen = new Pen( FrameBorderColor ) )
                    {
                        g.DrawPath( pen, childRect );
                    }
                    childRect = RoundedRectangle.Create( tabPadding + ( 80 * index ) + bounds.X + TabMargin + 1,
                                                         bounds.Y + 3, 80 - TabMargin,
                                                         TitleBarHeight - 8, 3,
                                                         RoundedRectangle.RectangleCorners.TopLeft |
                                                         RoundedRectangle.RectangleCorners.TopRight );
                    if ( index == ActiveItem )
                    {
                        using (
                            var br =
                                new LinearGradientBrush(
                                    new Rectangle( tabPadding + ( 80 * index ) + bounds.X + TabMargin + 1,
                                                   bounds.Y + 3, 80 - TabMargin,
                                                   TitleBarHeight - 8 ), Color.White, foreTabColor,
                                    LinearGradientMode.Vertical ) )
                        {
                            g.FillPath( br, childRect );
                        }

                        using ( var pen = new Pen( foreTabColor ) )
                        {
                            g.DrawLine( pen, tabPadding + TabMargin + 2 + ( 80 * index ),
                                        bounds.Y + 2 + TitleBarHeight - 6,
                                        tabPadding + 80 + TabMargin + ( 80 * index ),
                                        bounds.Y + 2 + TitleBarHeight - 6 );
                        }
                    }
                    else
                    {
                        using (
                            var br =
                                new LinearGradientBrush(
                                    new Rectangle( tabPadding + ( 80 * index ) + bounds.X + TabMargin + 1,
                                                   bounds.Y + 3, 80 - TabMargin,
                                                   TitleBarHeight - 8 ), foreTabColor, backTabsColor,
                                    LinearGradientMode.Vertical ) )
                        {
                            g.FillPath( br, childRect );
                        }
                    }


                    if ( !string.IsNullOrWhiteSpace( children.Title ) )
                    {
                        using (
                            var font = new Font( "Tahoma", 11, index == ActiveItem ? FontStyle.Bold : FontStyle.Regular,
                                                 GraphicsUnit.Pixel ) )
                        {
                            using ( var br = new SolidBrush( TitleFontColor ) )
                            {
                                var sf = new StringFormat();
                                sf.LineAlignment = StringAlignment.Center;
                                sf.Alignment = StringAlignment.Center;
                                sf.Trimming = StringTrimming.Character;
                                //var textSize = g.MeasureString( children.Title, font );
                                g.DrawString( children.Title, font, br,
                                              new Rectangle(
                                                  tabPadding + ( 80 * index ) + bounds.X + TabMargin + 1,
                                                  bounds.Y + 5, 78,
                                                  TitleBarHeight - 8 ), sf );
                            }
                        }
                    }


                    index++;
                    if ( tabPadding == 0 )
                        tabPadding = TabMargin;
                }

                bounds.Inflate( BorderWidth, BorderWidth );
            }
            using ( var pen = new Pen( FrameBorderColor ) )
            {
                var topBorderWidth = Border ? 1 : -1;
                g.DrawLine( pen, bounds.X + BorderWidth,
                            bounds.Y + TitleBarHeight + BorderWidth + topBorderWidth,
                            bounds.X + BorderWidth + bounds.Width - ( BorderWidth * 2 ),
                            bounds.Y + TitleBarHeight + BorderWidth + topBorderWidth );
            }
        }

        internal BoxComponent GetComponentAtPoint( Point point )
        {
            return ( from headersBound in _headersBounds
                     where headersBound.Value.Contains( point.X, point.Y )
                     select headersBound.Key ).FirstOrDefault();
        }
    }
}
